/*
Copyright (c) [2019年5月1日] [吴超]
[MBT_studio] is licensed under Mulan PSL v2.
You can use this software according to the terms and conditions of the Mulan PSL v2.
You may obtain a copy of Mulan PSL v2 at:
		 http://license.coscl.org.cn/MulanPSL2
THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
See the Mulan PSL v2 for more details.
*/
#include "stdafx.h"
#include "灯光节点.h"

#include "节点/插座/list/list物体插座.h"
#include "节点/插座/list/list数值插座.h"
#include "节点/插座/通用插座.h"
#include "节点/socket_utils.h"
#include "节点/节点树.h"

#include "Context/数据创建销毁.h"
#include "Context/当前默认操作数据.h"
#include "Context/虚拟体物体构建.h"



C_平行光节点::C_平行光节点(S_设备环境& ctx) : C_节点基类(DEF_平行光节点, E_节点类型::e_节点Type_灯光) {
	m_Ctx = ctx;
	f_setWName(u"平行光");
	//m_Ob = f_node_创建虚拟体网格物体(ctx, E_物体类型::t_平行光);
	//f_NodeCtx_录物体类节点(this, m_Ob);


	m_Ob = f_node_创建平行光虚拟体(ctx);
	m_Ob->m_Name = u"平行光虚拟体";
	m_Ob->m_颜色 = { 2,2,2,255 };

	f_ob_set数据槽数量(m_Ob, 2);
	f_ob_set数据(m_Ob, f_surface_创建实例(S_节点数据::g_me_灯光圆, true, true, true, false, true, true), 0);
	f_ob_set材质(m_Ob, f_NodeCtx_get基本光照线段材质(), 0);
	f_ob_set线宽(m_Ob, 2.0, 0);
	f_mesh_set绘制内存属性(f_ob_getMesh(m_Ob, 0), {});

	f_ob_set数据(m_Ob, f_surface_创建实例(S_节点数据::g_me_灯光平行线, true, true, true, false, true, true), E_物体网格元素类型::e_MT_面);
	f_ob_set材质(m_Ob, f_NodeCtx_get基本光照线段材质(), E_物体网格元素类型::e_MT_面);
	f_ob_set线宽(m_Ob, 1.0, 1);
	f_mesh_set绘制内存属性(f_ob_getMesh(m_Ob, E_物体网格元素类型::e_MT_面), {});

	f_ob_set颜色2(m_Ob, m_Ob->m_颜色, m_Ob->m_实例ID, 0);
	f_ob_set颜色2(m_Ob, m_Ob->m_颜色, m_Ob->m_实例ID, E_物体网格元素类型::e_MT_面);

	f_node_物体添加到主场景(m_Ob);
	f_node_物体添加到全局容器(m_Ob);


	m_灯光标志位 = f_alloc_UI32FlagBitsProp(nullptr, u"灯光遮罩");
	m_灯光标志位.m_私有 = true;
	f_prop_UI32(m_灯光标志位) = 1;


	C_插座基类* socket;
	DEF_创建Vec3插座_I(u"位置", &(m_Ob->m_变换.position));
	DEF_创建Vec3插座_I(u"旋转", &(m_Ob->m_变换.rotation));
	DEF_创建Vec3插座_I(u"缩放", &(m_Ob->m_变换.scale));

	DEF_创建Vec3插座_I(u"颜色", nullptr);
	DEF_创建F32插座_I(u"强度", nullptr);
	DEF_创建F32插座_I(u"散度", nullptr);
	DEF_创建F32插座_I(u"衰减", nullptr);
	//DEF_创建Vec3插座_I(u"颜色", &(light->m_color));
	//DEF_创建F32插座_I(u"强度", &(light->m_intensity));
	//DEF_创建F32插座_I(u"散度", &(light->m_diffusivity));
	//DEF_创建F32插座_I(u"衰减", &(light->m_falloff));

	DEF_创建物体插座_O(u"灯光物体");


	f_get输出插座(1)->f_setData(m_Ob);



	m_灯光数据 = f_bm_alloc(f_buf_getGlobal().m_平行光缓冲区, 1);
	m_Ob->m_ID = m_灯光数据.m_Mem.m_偏移;
	//f_scene_渲染器分配平行光内存(f_NodeCtx_get默认场景());
}

C_平行光节点::~C_平行光节点() {
	f_node_物体从主场景中移除(m_Ob);
	f_node_删除物体(m_Ob);

	f_bm_erase(m_灯光数据);
}

bool C_平行光节点::f_update() {
	S_LightParallel light{};

	vec3 dir = { 0, 1, 0 };
	auto mat = f_ob_get变换矩阵(m_Ob, m_Ob->m_实例ID);
	auto rotMat = f_mat44_to_33(mat, true);
	light.m_dir = rotMat * dir;
	light.m_color = { 1,1,1 };
	light.m_diffusivity = 0.1;
	light.m_enable = true;
	light.m_intensity = 1;
	light.m_mask = f_prop_UI32(m_灯光标志位);
	
	f_bm_at<S_LightParallel>(m_灯光数据, 0) = light;
	//f_scene_渲染器设置平行光(f_NodeCtx_get默认场景(), m_Ob->m_ID, light);
	//f_render_刷新渲染(f_NodeCtx_get默认场景());
	

	f_node_虚拟体_设置平行光虚拟网格(m_Ob);
	return false;
}

S_物体* C_平行光节点::f_虚拟体() {
	return m_Ob;
}

void C_平行光节点::f_删除() {
	assert(m_Ob);
	f_node_物体从主场景中移除(m_Ob);
	f_node_从全局容器移除物体(m_Ob);
	m_Ob->m_显示 = false;
	//f_node_移除虚拟体(m_Ob);
}

void C_平行光节点::f_回收() {
	f_node_物体添加到主场景(m_Ob);
	f_node_物体添加到全局容器(m_Ob);
	m_Ob->m_显示 = true;
	//f_node_创建平行光虚拟体(m_Ob);
}

void C_平行光节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	f_prop_Load(m_灯光标志位, f);
	f_ob_Load物体(m_Ob, f);
}

void C_平行光节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	f_prop_Save(m_灯光标志位, f);
	f_ob_Save物体(m_Ob, f);
}

C_节点基类* f_node_创建平行光节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_平行光节点(ctx);
}

C_节点基类* f_node_加载平行光节点(S_设备环境& ctx, FILE* f) {
	C_平行光节点* node = new C_平行光节点(ctx);
	return node;
}

void f_node_保存平行光节点(C_节点基类* n, FILE* f) {
	C_平行光节点* node = dynamic_cast<C_平行光节点*>(n);
}




C_点光源节点::C_点光源节点(S_设备环境& ctx) : C_节点基类(DEF_点光源节点, E_节点类型::e_节点Type_灯光) {
	m_Ctx = ctx;
	f_setWName(u"点光源");
	

	m_Ob = f_node_创建点光源虚拟体(ctx);
	m_Ob->m_颜色 = { 2,2,2,255 };

	f_NodeCtx_录物体类节点(this, m_Ob);
	f_node_物体添加到主场景(m_Ob);
	f_node_物体添加到全局容器(m_Ob);


	f_ob_set数据槽数量(m_Ob, 2);

	f_ob_set数据(m_Ob, f_surface_创建实例(S_节点数据::g_me_灯光圆, true, true, true, false, true, true), 0);
	f_ob_set材质(m_Ob, f_NodeCtx_get基本光照线段材质(), 0);
	f_ob_set线宽(m_Ob, 2.0, 0);
	f_mesh_set绘制内存属性(f_ob_getMesh(m_Ob, 0), {});

	f_ob_set数据(m_Ob, f_surface_创建实例(S_节点数据::g_me_范围圆, true, true, true, false, true, true), 1);
	f_ob_set材质(m_Ob, f_NodeCtx_get基本光照线段材质(), 1);
	f_ob_set线宽(m_Ob, 0.8, 1);
	f_mesh_set绘制内存属性(f_ob_getMesh(m_Ob, 1), {});

	

	f_ob_set颜色2(m_Ob, m_Ob->m_颜色, m_Ob->m_实例ID, 0);
	f_ob_set颜色2(m_Ob, m_Ob->m_颜色, m_Ob->m_实例ID, 1);

	f_mesh_计算包围盒(f_ob_getMesh(m_Ob, 1));

	

	m_灯光标志位 = f_alloc_UI32FlagBitsProp(nullptr, u"灯光遮罩");
	m_灯光标志位.m_私有 = true;
	f_prop_UI32(m_灯光标志位) = 1;


	m_点光源 = f_scene_渲染器分配点光源内存(f_NodeCtx_get默认场景());
	//C_插座基类* socket;
	//DEF_创建Vec3插座_I(u"位置", &(m_Ob->m_变换.location));
	//DEF_创建Vec3插座_I(u"缩放", &(m_Ob->m_变换.scale));
	DEF_创建F32插座_I(u"亮度", nullptr);
	DEF_创建F32插座_I(u"大小", nullptr);
	DEF_创建RGB插座_I(u"颜色");
	
	DEF_创建物体插座_I(u"物体");

	DEF_创建点光源插座_O(u"灯光物体");

	
	//DEF_Vec3插座数据(f_get输入插座(3)) = {1,1,1};
	DEF_F32插座数据(f_get输入插座(1)) = 1;
	DEF_F32插座数据(f_get输入插座(2)) = 0.1;
	DEF_Vec3插座数据(f_get输入插座(3)) = { 1,1,1 };
	
	//S_节点数据::G_点光源ID.f_Gen();

	m_点光源 = f_bm_alloc(f_buf_getGlobal().m_点光源缓冲区, 1);
	m_Ob->m_ID = m_点光源.m_Mem.m_偏移;

}

C_点光源节点::~C_点光源节点() {
	f_node_物体从主场景中移除(m_Ob);
	f_node_从全局容器移除物体(m_Ob);
	f_node_销毁虚拟体(m_Ob);
	f_node_删除物体(m_Ob);

	f_bm_erase(m_点光源);
}

bool C_点光源节点::f_update() {
	auto* socket1 = f_get输入插座(1);
	//auto* 灯光组 = DEF_物体插座_1D数据(socket1, 0);
	

	S_LightPoint light = {};
	light.m_pos = f_ob_get全局坐标(m_Ob, m_Ob->m_实例ID);
	light.m_falloff = m_Ob->m_变换.scale.x;

	light.m_intensity = DEF_F32插座数据(f_get输入插座(1));
	light.m_size = DEF_F32插座数据(f_get输入插座(2));
	light.m_color = DEF_Vec3插座数据(f_get输入插座(3));
	
	
	light.m_mask = f_prop_UI32(m_灯光标志位);
	light.m_enable = true;


	//f_scene_渲染器设置点光源(f_NodeCtx_get默认场景(), m_Ob->m_ID, light);
	(*f_buf_点光源_ptr(m_点光源)) = light;
	//f_render_刷新渲染(f_NodeCtx_get默认场景());


	//f_mesh_get网格元素绘制属性(f_ob_fromMesh(m_Ob, 1)) = f_init_MeshTranform();
	//f_mesh_get网格元素绘制属性(f_ob_fromMesh(m_Ob, 1)).m_Scale = 0.5;
	//f_mesh_get网格元素绘制属性(f_ob_fromMesh(m_Ob, 1)).m_TransformMode = DEF_MESH_LINE_TRANFORMTYPEMODEL_NBILLBOARD;
	f_node_虚拟体_设置点光源虚拟网格(m_Ob);


	DEF_点光源插座数据(f_get输出插座(1)) = light;
	return false;
}

S_物体* C_点光源节点::f_虚拟体() {
	//m_Ob = DEF_物体插座数据(f_get输出插座(1), 0);
	return m_Ob;
}

void C_点光源节点::f_删除() {
	assert(m_Ob);
	(*f_buf_点光源_ptr(m_点光源)).m_enable = false;
	//f_scene_渲染器设置点光源启用(f_NodeCtx_get默认场景(), m_Ob->m_ID, false);
	
	f_node_物体从主场景中移除(m_Ob);
	f_node_从全局容器移除物体(m_Ob);
}

void C_点光源节点::f_回收() {
	(*f_buf_点光源_ptr(m_点光源)).m_enable = true;
	//f_scene_渲染器设置点光源启用(f_NodeCtx_get默认场景(), m_Ob->m_ID, true);
	//m_Ob->m_显示 = true;
	//f_node_创建点光源虚拟体(m_Ob);
	f_node_物体添加到主场景(m_Ob);
	f_node_物体添加到全局容器(m_Ob);
}

void C_点光源节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	auto 文件块 = f_file_读取文件块(f);

	if (文件块.m_块类型 == E_节点工程文件块类型::e_工程文件块_节点实例属性) {
		const uint8* 下一次读取数据指针 = 文件块.m_data;
		//下一次读取数据指针 = f_ob_Load物体(m_Ob, 下一次读取数据指针);
		//下一次读取数据指针 = f_prop_Load(m_灯光标志位, 下一次读取数据指针);
	}
	free(文件块.m_data);
}

void C_点光源节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	auto 文件块 = f_文件块_创建(E_节点工程文件块类型::e_工程文件块_节点实例属性, S_引擎配置::g_文件版本号);

	S_UI8Array* 块 = (S_UI8Array*)f_core_array_new(0, sizeof(uint8));
	f_ob_Save物体(m_Ob, 块);
	f_prop_Save(m_灯光标志位, 块);

	f_file_保存文件块(f, 文件块, 块);
}

C_节点基类* f_node_创建点光源节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_点光源节点(ctx);
}

C_节点基类* f_node_加载点光源节点(S_设备环境& ctx, FILE* f) {
	C_点光源节点* node = new C_点光源节点(ctx);
	return node;
}

void f_node_保存点光源节点(C_节点基类* n, FILE* f) {
	C_点光源节点* node = dynamic_cast<C_点光源节点*>(n);
}




C_聚光灯节点::C_聚光灯节点(S_设备环境& ctx) : C_节点基类(DEF_聚光灯节点, E_节点类型::e_节点Type_灯光) {
	m_Ctx = ctx;
	f_setWName(u"聚光灯");
	m_Ob = f_node_创建虚拟体网格物体(ctx, E_物体类型::t_聚光灯);
	f_NodeCtx_录物体类节点(this, m_Ob);


	m_灯光标志位 = f_alloc_UI32FlagBitsProp(nullptr, u"灯光遮罩");
	m_灯光标志位.m_私有 = true;
	f_prop_UI32(m_灯光标志位) = 1;


	C_插座基类* socket;
	DEF_创建Vec3插座_I(u"位置", &(m_Ob->m_变换.position));
	DEF_创建Vec3插座_I(u"旋转", &(m_Ob->m_变换.rotation));
	DEF_创建Vec3插座_I(u"缩放", &(m_Ob->m_变换.scale));
	DEF_创建F32插座_I(u"散度", nullptr);

	DEF_创建物体插座_O(u"灯光物体");


	f_get输出插座(1)->f_setData(m_Ob);
}

C_聚光灯节点::~C_聚光灯节点() {
	f_node_物体从主场景中移除(m_Ob);
	f_node_删除物体(m_Ob);
}

bool C_聚光灯节点::f_update() {
	DEF_Vec3插座数据(f_get输入插座(2)).y = 0;

	f_node_设置灯光虚拟网格范围(m_Ob, { 0, m_Ob->m_变换.scale.y });
	//f_render_刷新渲染(f_NodeCtx_get默认场景());

	//auto mesh = f_ob_fromMesh(m_Ob, 0);
	//m_Ob->m_Bound = f_surface_计算包围盒(mesh, nullptr, m_Ob->m_PickIndirect.firstVertex, m_Ob->m_PickIndirect.vertexCount);
	//light.m_maks = f_prop_UI32(m_灯光标志位);


	return false;
}

S_物体* C_聚光灯节点::f_虚拟体() {
	//m_Ob = DEF_物体插座数据(f_get输出插座(1), 0);
	return m_Ob;
}

void C_聚光灯节点::f_删除() {
	assert(m_Ob);
	//f_scene_渲染器设置聚光灯启用(f_NodeCtx_get默认场景(), m_Ob->m_ID, false);
	f_node_移除虚拟体(m_Ob);
}

void C_聚光灯节点::f_回收() {
	//f_scene_渲染器设置聚光灯启用(f_NodeCtx_get默认场景(), m_Ob->m_ID, true);
	f_node_创建聚光灯虚拟体(m_Ob);
	
}

void C_聚光灯节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	auto 文件块 = f_file_读取文件块(f);

	if (文件块.m_块类型 == E_节点工程文件块类型::e_工程文件块_节点实例属性) {
		const uint8* 下一次读取数据指针 = 文件块.m_data;
		//下一次读取数据指针 = f_ob_Load物体(m_Ob, 下一次读取数据指针);
		//下一次读取数据指针 = f_prop_Load(m_灯光标志位, 下一次读取数据指针);
	}
	free(文件块.m_data);
}

void C_聚光灯节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);
	auto 文件块 = f_文件块_创建(E_节点工程文件块类型::e_工程文件块_节点实例属性, S_引擎配置::g_文件版本号);

	S_UI8Array* 块 = (S_UI8Array*)f_core_array_new(0, sizeof(uint8));
	f_ob_Save物体(m_Ob, 块);
	f_prop_Save(m_灯光标志位, 块);
	
	f_file_保存文件块(f, 文件块, 块);
}

C_节点基类* f_node_创建聚光灯节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_聚光灯节点(ctx);
}

C_节点基类* f_node_加载聚光灯节点(S_设备环境& ctx, FILE* f) {
	C_聚光灯节点* node = new C_聚光灯节点(ctx);
	return node;
}

void f_node_保存聚光灯节点(C_节点基类* n, FILE* f) {
	C_聚光灯节点* node = dynamic_cast<C_聚光灯节点*>(n);
}



C_区域光节点::C_区域光节点(S_设备环境& ctx) : C_节点基类(DEF_区域光节点, E_节点类型::e_节点Type_灯光) {
	m_Ctx = ctx;
	f_setWName(u"区域光");
	

	DEF_创建颜色插座_I(u"颜色", nullptr);
	DEF_创建F32插座_I(u"强度", nullptr);
	DEF_创建F32插座_I(u"距离", nullptr);
	DEF_创建F32插座_I(u"散度", nullptr);

	DEF_创建F32插座_I(u"衰减", nullptr);


	DEF_创建物体插座_O(u"灯光物体");

	DEF_颜色插座数据(f_get输入插座(1)) = { 1,1,1, 1 };
	DEF_F32插座数据(f_get输入插座(2)) = 0.5;
	DEF_F32插座数据(f_get输入插座(3)) = 1000;
	DEF_F32插座数据(f_get输入插座(4)) = 0.1;



	
	m_灯光标志位 = f_alloc_UI32FlagBitsProp(nullptr, u"灯光遮罩");
	m_灯光标志位.m_私有 = true;
	f_prop_UI32(m_灯光标志位) = 1;


	

	m_发光类型 = f_alloc_EnumProp(nullptr, { {u"单色"},{u"渐变"},{u"径向"} }, u"发光类型");
	m_发光类型.m_私有 = true;


	m_阴影 = f_alloc_BoolProp(nullptr, u"阴影", true);
	m_阴影.m_私有 = true;
	
	m_阴影纹理大小 = f_alloc_EnumProp(nullptr, { {u"512"},{u"1024"},{u"2048"},{u"4096"},{u"8192"} }, u"阴影大小");
	m_阴影纹理大小.m_私有 = true;

	m_阴影采样数量 = f_alloc_UI32Prop(nullptr, u"采样数量", 1);
	m_阴影采样数量.m_私有 = true;

	m_阴影模糊厚度 = f_alloc_F32Prop(nullptr, u"阴影模糊厚度", 1);
	m_阴影模糊厚度.m_私有 = true;

	m_阴影模糊长度 = f_alloc_F32Prop(nullptr, u"阴影模糊长度", 3);
	m_阴影模糊长度.m_私有 = true;


	m_形状类型 = f_alloc_EnumProp(nullptr, { {u"矩形",u""}, {u"圆形"} }, u"形状");
	m_形状类型.m_私有 = true;

	m_阴影采样方式 = f_alloc_EnumProp(nullptr, { {u"透视",u""}, {u"正交"} }, u"采样方式", E_投影模式::e_正交);
	m_阴影采样方式.m_私有 = true;

	m_高光比 = f_alloc_F32Prop(nullptr, u"高光比", 0.5);
	m_高光比.m_私有 = true;
	
	m_高光 = f_alloc_F32Prop(nullptr, u"高光", 1);
	m_高光.m_私有 = true;

	m_阴影纹理 = f_alloc_Prop纹理集(nullptr, u"阴影贴图");
	m_阴影纹理.m_私有 = true;

	m_Ob = f_ob_创建区域光(ctx);
	f_ob_set数据槽数量(m_Ob, 4);
	
	f_ob_set数据(m_Ob, f_surface_创建实例(S_节点数据::g_me_灯光圆, true, true, true, false, true, true), 1);
	f_ob_set材质(m_Ob, f_NodeCtx_get基本光照线段材质(), 1);
	f_ob_set线宽(m_Ob, 2.0, 1);
	f_mesh_set绘制内存属性(f_ob_getMesh(m_Ob, 1), {});
	
	f_ob_set数据(m_Ob, f_surface_创建实例(S_节点数据::g_me_区域光四边线, true, true, true, false, true, true), 2);
	f_ob_set材质(m_Ob, f_NodeCtx_get基本光照线段材质(), 2);
	f_ob_set线宽(m_Ob, 1.0, 2);
	f_mesh_set绘制内存属性(f_ob_getMesh(m_Ob, 2), {});
	
	f_ob_set数据(m_Ob, f_surface_创建实例(S_节点数据::g_me_四边型, true, true, true, false, true, true), 3);
	f_ob_set材质(m_Ob, f_NodeCtx_get基本光照线段材质(), 3);
	f_ob_set线宽(m_Ob, 1.0, 3);
	f_mesh_set绘制内存属性(f_ob_getMesh(m_Ob, 3), {});
	
	f_ob_set颜色2(m_Ob, m_Ob->m_颜色, m_Ob->m_实例ID, 1);
	f_ob_set颜色2(m_Ob, m_Ob->m_颜色, m_Ob->m_实例ID, 2);
	f_ob_set颜色2(m_Ob, m_Ob->m_颜色, m_Ob->m_实例ID, 3);
	
	f_mesh_计算包围盒(f_ob_getMesh(m_Ob, 1));
	f_mesh_计算包围盒(f_ob_getMesh(m_Ob, 2));
	f_mesh_计算包围盒(f_ob_getMesh(m_Ob, 3));


	f_node_物体添加到主场景(m_Ob);
	f_node_物体添加到全局容器(m_Ob);


	f_get输出插座(1)->f_setData(m_Ob);
	f_NodeCtx_录物体类节点(this, m_Ob);

	


	m_灯光 = f_ob_创建灯光(ctx, E_物体类型::t_区域光);
	f_ob_add子物体(m_Ob, m_灯光);

	auto* lp = f_ob_getLigth(m_灯光);
	f_更新阴影纹理(lp);

}

C_区域光节点::~C_区域光节点() {
	f_prop_Release(m_形状类型);
	f_prop_Release(m_发光类型);

	f_prop_Release(m_阴影纹理);
	f_prop_Release(m_阴影纹理大小);
	f_prop_Release(m_阴影采样数量);
	f_prop_Release(m_阴影模糊厚度);
	f_prop_Release(m_阴影模糊长度);

	f_prop_Release(m_高光比);
	f_prop_Release(m_高光);

	//auto* lp = f_ob_getLigth(m_灯光);
	//f_light_free灯光场景数据(lp);

	
	auto 材质 = f_ob_get材质(m_Ob, 0);
	delete 材质;


	f_node_物体从主场景中移除(m_Ob);
	f_node_删除物体(m_Ob);


}

void C_区域光节点::f_更新阴影纹理(S_灯光场景数据* lp) {
	uint32 分辨率 = f_prop_enum(m_阴影纹理大小);
	uint32 采样数量 = f_prop_UI32(m_阴影采样数量);

	uint32 纹理大小;
	switch (分辨率) {
		case 0: 纹理大小 = 512; break;
		case 1: 纹理大小 = 1024; break;
		case 2: 纹理大小 = 2048; break;
		case 3: 纹理大小 = 4096; break;
		case 4: 纹理大小 = 8192; break;
		default:
			纹理大小 = 512;
			break;
	}

	switch (f_prop_enum(m_阴影采样方式)) {
		case E_投影模式::e_透视: {
			//采样数量 = 2;
			break;
		}
		case E_投影模式::e_正交: {
			break;
		}
	}

	f_light_构建阴影图(lp, { 纹理大小, 纹理大小 }, 采样数量);
	f_light_set阴影贴图大小(lp, { 纹理大小, 纹理大小 });


	auto& ts = f_prop_纹理集(m_阴影纹理);
	f_纹理集_set数量(ts.m_纹理集, 采样数量);
	for (uint32 i = 0; i < 采样数量; ++i) {
		f_纹理集_set纹理(ts.m_纹理集, lp->m_阴影图->ptr_userData[i], i);
	}

	
}

bool C_区域光节点::f_update() {
	//return false;
	auto* lp = f_ob_getLigth(m_灯光);
	S_LightArea& light = f_bm_at<S_LightArea>(lp->m_灯光数据, 0);

	f_更新阴影纹理(lp);


	light.m_color = _Vec3(DEF_颜色插座数据(f_get输入插座(1)));
	light.m_intensity = DEF_F32插座数据(f_get输入插座(2));
	light.m_dis = DEF_F32插座数据(f_get输入插座(3));
	light.m_diffusivity = DEF_F32插座数据(f_get输入插座(4));
	light.m_falloff = DEF_F32插座数据(f_get输入插座(5));
	light.m_specular = f_prop_F32(m_高光);

	light.m_mask = f_prop_UI32(m_灯光标志位);
	light.m_enable = true;
	light.m_samplerType_samplerNum = (f_prop_enum(m_阴影采样方式) << 16) | lp->m_阴影图->count;
	light.m_thickness = f_prop_F32(m_阴影模糊厚度);
	light.m_contactShadowLength = f_prop_F32(m_阴影模糊长度);
	//f_scene_渲染器设置区域光(f_NodeCtx_get默认场景(), m_Ob->m_ID, light);
	//f_render_刷新渲染(f_NodeCtx_get默认场景());
	light.m_width = 1;
	light.m_height = 1;

	//light.m_pos = f_ob_get全局坐标(m_灯光, 0);
	//light.m_dir = normalize(f_ob_get全局旋转(m_灯光, {0,0,-1}, 0));
	
	
	f_node_虚拟体_设置区域光虚拟网格(m_Ob);

	float32 高光比 = f_prop_F32(m_高光比);
	auto me = f_ob_getMesh(m_Ob, 2);
	f_bm_at<S_MeshTranformProp>(me->m_网格元素变换属性).m_Scale = 高光比;



	uint32 材质ID = 0;
	S_Material& 灯光材质 = f_ob_get材质属性(材质ID, m_Ob, 0);
	灯光材质.m_color = light.m_color;
	灯光材质.m_emission = _Vec3(light.m_specular);

	S_Mesh* 发光区 = f_ob_getMesh(m_Ob, 0);
	S_MeshTranformProp& 发光区变换属性 = f_buf_网格元素变换属性_at(发光区->m_网格元素变换属性, m_灯光->m_实例ID);
	发光区变换属性.m_Scale = 高光比;
	发光区变换属性.m_MaterialID = 材质ID;



	return false;
}

S_物体* C_区域光节点::f_虚拟体() {
	//m_Ob = DEF_物体插座数据(f_get输出插座(1), 0);
	
	return m_Ob;
}

void C_区域光节点::f_删除() {
	assert(m_Ob);
	//f_scene_渲染器设置区域光启用(f_NodeCtx_get默认场景(), m_Ob->m_ID, false);
	//f_node_移除虚拟体(m_Ob);
	f_node_物体从主场景中移除(m_Ob);
	f_node_从全局容器移除物体(m_Ob);
}

void C_区域光节点::f_回收() {
	//f_scene_渲染器设置区域光启用(f_NodeCtx_get默认场景(), m_Ob->m_ID, true);
	//f_node_创建聚光灯虚拟体(m_Ob);
	f_node_物体添加到主场景(m_Ob);
	f_node_物体添加到全局容器(m_Ob);
}

void C_区域光节点::f_切换区域光形状() {
	
}

void C_区域光节点::f_读取(FILE* f) {
	C_节点基类::f_读取(f);
	S_文件块 文件块 = f_file_读取文件块(f);
	if (文件块.m_块类型 == E_节点工程文件块类型::e_工程文件块_节点实例属性) {
		const uint8* 下一次读取数据指针 = 文件块.m_data;
	
		if (f_file_版本对比(文件块, S_引擎配置::g_低版本号_5, S_引擎配置::g_文件版本号)) {
			下一次读取数据指针 = f_prop_Load(m_形状类型, 下一次读取数据指针);
			下一次读取数据指针 = f_prop_Load(m_灯光标志位, 下一次读取数据指针);
	
			下一次读取数据指针 = f_prop_Load(m_阴影, 下一次读取数据指针);
			下一次读取数据指针 = f_prop_Load(m_阴影纹理大小, 下一次读取数据指针);
			下一次读取数据指针 = f_prop_Load(m_阴影采样数量, 下一次读取数据指针);
			下一次读取数据指针 = f_prop_Load(m_阴影采样方式, 下一次读取数据指针);

			下一次读取数据指针 = f_prop_Load(m_阴影模糊厚度, 下一次读取数据指针);
			下一次读取数据指针 = f_prop_Load(m_阴影模糊长度, 下一次读取数据指针);

			下一次读取数据指针 = f_prop_Load(m_高光比, 下一次读取数据指针);
			下一次读取数据指针 = f_prop_Load(m_高光, 下一次读取数据指针);
	
			//下一次读取数据指针 = f_ob_Load物体(m_Ob, 下一次读取数据指针);
		}
	}
	free(文件块.m_data);
}

void C_区域光节点::f_写入(FILE* f) {
	C_节点基类::f_写入(f);

	auto 文件块 = f_文件块_创建(E_节点工程文件块类型::e_工程文件块_节点实例属性, S_引擎配置::g_文件版本号);
	S_UI8Array* 块 = (S_UI8Array*)f_core_array_new(0, sizeof(uint8));

	f_prop_Save(m_形状类型, 块);
	f_prop_Save(m_灯光标志位, 块);
	f_prop_Save(m_阴影, 块);
	f_prop_Save(m_阴影纹理大小, 块);
	f_prop_Save(m_阴影采样数量, 块);
	f_prop_Save(m_阴影采样方式, 块);

	f_prop_Save(m_阴影模糊厚度, 块);
	f_prop_Save(m_阴影模糊长度, 块);

	f_prop_Save(m_高光比, 块);
	f_prop_Save(m_高光, 块);
	
	//f_ob_Save物体(m_Ob, 块);

	f_file_保存文件块(f, 文件块, 块);
}

C_节点基类* f_node_创建面光源节点(S_设备环境& ctx, C_节点树* 子节点树) {
	return new C_区域光节点(ctx);
}

C_节点基类* f_node_加载面光源节点(S_设备环境& ctx, FILE* f) {
	C_区域光节点* node = new C_区域光节点(ctx);
	return node;
}

void f_node_保存面光源节点(C_节点基类* n, FILE* f) {
	C_区域光节点* node = dynamic_cast<C_区域光节点*>(n);
}



